From fefc980d1c009752df03dd018216eb1588d2f9e0 Mon Sep 17 00:00:00 2001
From: Alex Suykov <alex.suykov@gmail.com>
Date: Sun, 21 Jan 2018 04:05:14 +0200
Subject: [PATCH xserver 6/8] config/udev: drop ID_INPUT code

Query event bits directly instead.

XKB/udevd configuration code goes out as well, it is prone to the same
kind of race conditions and the whole idea of using udev to configure
X-specific properties is just dumb.

Signed-off-by: Alex Suykov <alex.suykov@gmail.com>
---
 config/udev.c | 151 ++++++++++++++++++----------------------------------------
 1 file changed, 47 insertions(+), 104 deletions(-)

diff --git a/config/udev.c b/config/udev.c
index 1a6021262..1d4b4687a 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -39,19 +39,6 @@
 #include "globals.h"
 #include "systemd-logind.h"
 
-#define UDEV_XKB_PROP_KEY "xkb"
-
-#define LOG_PROPERTY(path, prop, val)                                   \
-    LogMessageVerb(X_INFO, 10,                                          \
-                   "config/udev: getting property %s on %s "            \
-                   "returned \"%s\"\n",                                 \
-                   (prop), (path), (val) ? (val) : "(null)")
-#define LOG_SYSATTR(path, attr, val)                                    \
-    LogMessageVerb(X_INFO, 10,                                          \
-                   "config/udev: getting attribute %s on %s "           \
-                   "returned \"%s\"\n",                                 \
-                   (attr), (path), (val) ? (val) : "(null)")
-
 static struct udev_monitor *udev_monitor;
 
 #ifdef CONFIG_UDEV_KMS
@@ -108,7 +95,8 @@ device_added_drm(struct udev_device *udev_device,
 }
 
 static const char*
-query_input_name_ids(struct udev_device* parent, InputAttributes* attrs)
+query_input_name_ids(struct udev_device* parent, InputAttributes* attrs,
+                     const char* path)
 {
     const char *ppath = udev_device_get_devnode(parent);
     const char *product = udev_device_get_property_value(parent, "PRODUCT");
@@ -116,10 +104,10 @@ query_input_name_ids(struct udev_device* parent, InputAttributes* attrs)
     unsigned int vendor, model;
     const char* name = NULL;
 
-    if ((name = udev_device_get_sysattr_value(parent, "name")))
-        LOG_SYSATTR(ppath, "name", name);
-    else if((name = udev_device_get_property_value(parent, "NAME")))
-        LOG_PROPERTY(ppath, "NAME", name);
+    name = udev_device_get_sysattr_value(parent, "name");
+
+    if (!name)
+        name = udev_device_get_property_value(parent, "NAME");
     if (name)
         attrs->product = strdup(name);
 
@@ -129,7 +117,8 @@ query_input_name_ids(struct udev_device* parent, InputAttributes* attrs)
         if (asprintf(&usb_id, "%04x:%04x", vendor, model) == -1)
             usb_id = NULL;
         else
-            LOG_PROPERTY(ppath, "PRODUCT", product);
+            LogMessage(X_INFO, "config/udev: %s usb-id \"%s\"\n",
+                    path, usb_id);
         attrs->usb_id = usb_id;
     }
 
@@ -137,7 +126,8 @@ query_input_name_ids(struct udev_device* parent, InputAttributes* attrs)
         if ((pnp_id = udev_device_get_sysattr_value(parent, "id"))) {
             attrs->pnp_id = strdup(pnp_id);
             ppath = udev_device_get_devnode(parent);
-            LOG_SYSATTR(ppath, "id", pnp_id);
+            LogMessage(X_INFO, "config/udev: %s pnp-id \"%s\" via %s\n",
+                    path, pnp_id, ppath);
             break;
         }
     }
@@ -145,26 +135,50 @@ query_input_name_ids(struct udev_device* parent, InputAttributes* attrs)
     return name;
 }
 
+static void
+query_input_event_bits(struct udev_device* parent, InputAttributes* attrs,
+                       const char* path)
+{
+    const char* key = udev_device_get_property_value(parent, "KEY");
+    const char* rel = udev_device_get_property_value(parent, "REL");
+    const char* abs = udev_device_get_property_value(parent, "ABS");
+    int flags = 0;
+
+    if (abs) {
+        LogMessage(X_INFO, "config/udev: %s is a touchpad\n", path);
+        flags |= ATTR_TOUCHPAD;
+    } else if (rel) {
+        LogMessage(X_INFO, "config/udev: %s is a pointer\n", path);
+        flags |= ATTR_POINTER;
+    } else if (key) {
+        LogMessage(X_INFO, "config/udev: %s is a keyboard\n", path);
+        flags |= ATTR_KEY | ATTR_KEYBOARD;
+    }
+
+    attrs->flags |= flags;
+}
+
 static void
 device_added_input(struct udev_device *udev_device,
                    const char* path, const char* syspath)
 {
     const char *name = NULL;
     char *config_info = NULL;
-    const char *tags_prop;
-    const char *key, *value, *tmp;
     InputOption *input_options;
     InputAttributes attrs = { };
     DeviceIntPtr dev = NULL;
-    struct udev_list_entry *set, *entry;
     int rc;
 
+    const char *sysname = udev_device_get_sysname(udev_device);
     struct udev_device *parent = udev_device_get_parent(udev_device);
     dev_t devnum = udev_device_get_devnum(udev_device);
 
-    value = udev_device_get_property_value(udev_device, "ID_INPUT");
-    if (value && !strcmp(value, "0")) {
-        LogMessageVerb(X_INFO, 10, "config/udev: ignoring device %s", path);
+    if (asprintf(&config_info, "udev:%s", syspath) == -1)
+        return;
+
+    if (device_is_duplicate(config_info)) {
+        free(config_info);
+        LogMessage(X_WARNING, "config/udev: %s already added\n", path);
         return;
     }
 
@@ -173,7 +187,9 @@ device_added_input(struct udev_device *udev_device,
         return;
 
     if (parent)
-        name = query_input_name_ids(parent, &attrs);
+        name = query_input_name_ids(parent, &attrs, path);
+    if (name)
+        LogMessage(X_INFO, "config/udev: %s name \"%s\"\n", path, name);
     if (!name)
         name = "(unnamed)";
 
@@ -185,80 +201,8 @@ device_added_input(struct udev_device *udev_device,
     if (path)
         attrs.device = strdup(path);
 
-    tags_prop = udev_device_get_property_value(udev_device, "ID_INPUT.tags");
-    LOG_PROPERTY(path, "ID_INPUT.tags", tags_prop);
-    attrs.tags = xstrtokenize(tags_prop, ",");
-
-    if (asprintf(&config_info, "udev:%s", syspath) == -1) {
-        config_info = NULL;
-        goto unwind;
-    }
-
-    if (device_is_duplicate(config_info)) {
-        LogMessage(X_WARNING, "config/udev: device %s already added. ", name);
-        goto unwind;
-    }
-
-    set = udev_device_get_properties_list_entry(udev_device);
-    udev_list_entry_foreach(entry, set) {
-        key = udev_list_entry_get_name(entry);
-        if (!key)
-            continue;
-        value = udev_list_entry_get_value(entry);
-        if (!strncasecmp(key, UDEV_XKB_PROP_KEY, sizeof(UDEV_XKB_PROP_KEY) - 1)) {
-            LOG_PROPERTY(path, key, value);
-            tmp = key + sizeof(UDEV_XKB_PROP_KEY) - 1;
-            if (!strcasecmp(tmp, "rules"))
-                input_options =
-                    input_option_new(input_options, "xkb_rules", value);
-            else if (!strcasecmp(tmp, "layout"))
-                input_options =
-                    input_option_new(input_options, "xkb_layout", value);
-            else if (!strcasecmp(tmp, "variant"))
-                input_options =
-                    input_option_new(input_options, "xkb_variant", value);
-            else if (!strcasecmp(tmp, "model"))
-                input_options =
-                    input_option_new(input_options, "xkb_model", value);
-            else if (!strcasecmp(tmp, "options"))
-                input_options =
-                    input_option_new(input_options, "xkb_options", value);
-        }
-        else if (!strcmp(key, "ID_VENDOR")) {
-            LOG_PROPERTY(path, key, value);
-            attrs.vendor = strdup(value);
-        } else if (!strncmp(key, "ID_INPUT_", 9)) {
-            const struct pfmap {
-                const char *property;
-                unsigned int flag;
-            } map[] = {
-                { "ID_INPUT_KEY", ATTR_KEY },
-                { "ID_INPUT_KEYBOARD", ATTR_KEYBOARD },
-                { "ID_INPUT_MOUSE", ATTR_POINTER },
-                { "ID_INPUT_JOYSTICK", ATTR_JOYSTICK },
-                { "ID_INPUT_TABLET", ATTR_TABLET },
-                { "ID_INPUT_TABLET_PAD", ATTR_TABLET_PAD },
-                { "ID_INPUT_TOUCHPAD", ATTR_TOUCHPAD },
-                { "ID_INPUT_TOUCHSCREEN", ATTR_TOUCHSCREEN },
-                { NULL, 0 },
-            };
-
-            /* Anything but the literal string "0" is considered a
-             * boolean true. The empty string isn't a thing with udev
-             * properties anyway */
-            if (value && strcmp(value, "0")) {
-                const struct pfmap *m = map;
-
-                while (m->property != NULL) {
-                    if (!strcmp(m->property, key)) {
-                        LOG_PROPERTY(path, key, value);
-                        attrs.flags |= m->flag;
-                    }
-                    m++;
-                }
-            }
-        }
-    }
+    if (sysname && !strncmp(sysname, "event", 5) && parent)
+        query_input_event_bits(parent, &attrs, path);
 
     input_options = input_option_new(input_options, "config_info", config_info);
 
@@ -269,11 +213,10 @@ device_added_input(struct udev_device *udev_device,
     rc = NewInputDeviceRequest(input_options, &attrs, &dev);
 
     if (rc != Success)
-        LogMessage(X_INFO, "config/udev: cannot add %s (%s)\n", name, path);
+        LogMessage(X_INFO, "config/udev: %s cannot be added (%i)\n", path, rc);
     else
-        LogMessage(X_INFO, "config/udev: adding %s (%s)\n", name, path);
+        LogMessage(X_INFO, "config/udev: %s added successfully\n", path);
 
- unwind:
     free(config_info);
     input_option_free_list(&input_options);
 
-- 
2.16.1

